package com.share.payment.service.impl;

import com.alibaba.fastjson2.JSON;
import com.share.common.core.domain.R;
import com.share.common.core.utils.StringUtils;
import com.share.payment.config.WxPayV3Properties;
import com.share.payment.domain.CreateWxPaymentForm;
import com.share.payment.domain.PaymentInfo;
import com.share.payment.domain.WxPrepayVo;
import com.share.payment.service.PaymentInfoService;
import com.share.payment.service.WxPayService;
import com.share.user.api.RemoteUserInfoService;
import com.share.user.api.domain.UserInfo;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;


@Slf4j
@Service
public class WxPayServiceImpl implements WxPayService {
    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private WxPayV3Properties wxPayV3Properties;

    @Autowired
    private RSAAutoCertificateConfig rsaAutoCertificateConfig;

    @Override
    public WxPrepayVo createWxPayment(CreateWxPaymentForm createWxPaymentForm) {
        try {
            //保存支付记录
            PaymentInfo paymentInfo = paymentInfoService.savePaymentInfo(createWxPaymentForm.getOrderNo());

            //获取用户信息
            R<UserInfo> userInfoResult = remoteUserInfoService.getUserInfo(paymentInfo.getUserId());
            if (StringUtils.isNull(userInfoResult) || StringUtils.isNull(userInfoResult.getData())) {
                throw new com.share.common.core.exception.ServiceException("获取用户信息失败");
            }
            if (R.FAIL == userInfoResult.getCode()) {
                throw new com.share.common.core.exception.ServiceException(userInfoResult.getMsg());
            }
            String openid = userInfoResult.getData().getWxOpenId();

            // 构建service
            JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();

            // request.setXxx(val)设置所需参数，具体参数可见Request定义
            PrepayRequest request = new PrepayRequest();
            Amount amount = new Amount();
            amount.setTotal(paymentInfo.getAmount().multiply(new BigDecimal(100)).intValue());
            request.setAmount(amount);
            request.setAppid(wxPayV3Properties.getAppid());
            request.setMchid(wxPayV3Properties.getMerchantId());
            request.setDescription(paymentInfo.getContent());
            request.setNotifyUrl(wxPayV3Properties.getNotifyUrl());
            request.setOutTradeNo(paymentInfo.getOrderNo());

            //获取用户信息
            Payer payer = new Payer();
            payer.setOpenid(openid);
            request.setPayer(payer);

            // 调用下单方法，得到应答
            // response包含了调起支付所需的所有参数，可直接用于前端调起支付
            PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
            log.info("微信支付下单返回参数：{}", JSON.toJSONString(response));

            WxPrepayVo wxPrepayVo = new WxPrepayVo();
            BeanUtils.copyProperties(response, wxPrepayVo);
            wxPrepayVo.setTimeStamp(response.getTimeStamp());

            return wxPrepayVo;
        } catch (ServiceException e) {
            e.printStackTrace();
            throw new com.share.common.core.exception.ServiceException(e.getErrorMessage());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            throw new com.share.common.core.exception.ServiceException("订单号不存在");
        } catch (Exception e) {
            e.printStackTrace();
            throw new com.share.common.core.exception.ServiceException("微信下单异常");
        }
    }
}
